/*
 * Copyright (c) 2007-2008, Thomas Krause (tho.krause@gmail.com)
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 *     * Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *     * Neither the name of gidoo nor the names of its contributors may be used to
 *       endorse or promote products derived from this software without specific
 *       prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.gidoo.cms.data;

import java.io.Serializable;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

/**
 * Represents a single user. A user can be an editor or publisher for certain
 * sections. Some users also have administration rights. The user should not be 
 * deleted after he is not longer a member of the website team because the
 * information about who edited or published something is only stored as
 * references from the pages. Instead you should deactivate it's rights.
 *  
 * @author <a href="mailto:tho.krause@gmail.com">Thomas Krause</a>
 */
@Entity
@Table(
  uniqueConstraints={@UniqueConstraint(columnNames={"loginName"})}
)
public class RegisteredUser implements Serializable, Comparable<RegisteredUser>
{
 
  private long id;
  
  private String loginName;
  
  private String fullName;
  
  private String email;
  
  private boolean isAdmin;
  
  private String passwordHash;
  private List<CMSSection> sections_edit;
  private List<CMSSection> sections_publish;
  
  public RegisteredUser()
  {
  }

  /** Get the email adress */
  @Column(nullable=false)
  public String getEmail()
  {
    return email;
  }
  
  /** Set the email adress */
  public void setEmail(String email)
  {
    this.email = email;
  }

  /** Get the full name. */
  @Column(nullable=false)
  public String getFullName()
  {
    return fullName;
  }
  
  /** Set the full name. */
  public void setFullName(String fullName)
  {
    this.fullName = fullName;
  }

  @Id
  @GeneratedValue
  public long getId()
  {
    return id;
  }

  public void setId(long id)
  {
    this.id = id;
  }

  /** 
   * Get wether the user is an administrator. Administrators have the right to
   * change the permissions and the informations about the users. They further
   * can create and delete sections and perform other adminstrative tasks.
   */
  @Column(nullable=false)
  public boolean getIsAdmin()
  {
    return isAdmin;
  }

  /** 
   * Set wether the user is an administrator. Administrators have the right to
   * change the permissions and the informations about the users. They further
   * can create and delete sections and perform other adminstrative tasks.
   */
  public void setIsAdmin(boolean isAdmin)
  {
    this.isAdmin = isAdmin;
  }

  /** Get the unique login name (sometimes calles "username") */
  @Column(nullable=false)
  public String getLoginName()
  {
    return loginName;
  }

  /** Set the unique login name (sometimes calles "username") */
  public void setLoginName(String loginName)
  {
    this.loginName = loginName;
  }

  /** 
   * Get the password hash. The password is not stored directly in the database
   * but using hashing. Currently SHA hashing should be used.
   */
  @Column(nullable=false)
  public String getPasswordHash()
  {
    return passwordHash;
  }

  /** 
   * Set the password hash. The password is not stored directly in the database
   * but using hashing. Currently SHA hashing should be used.
   */
  public void setPasswordHash(String passwordHash)
  {
    this.passwordHash = passwordHash;
  }

  /** Get the list of the sections the user might edit */
  @ManyToMany(mappedBy = "editors")
  public List<CMSSection> getSections_edit()
  {
    return  sections_edit;
  }

  /** Set the list of the sections the user might edit */
  public void setSections_edit(List<CMSSection> pages_edit)
  {
    this. sections_edit = pages_edit;
  }

  /**
   * Get the list of the sections the user might publish
   */
  @ManyToMany(mappedBy = "publishers")
  public List<CMSSection> getSections_publish()
  {
    return  sections_publish;
  }

  /**
   * Set the list of the sections the user might publish
   */
  public void setSections_publish(List<CMSSection> pages_publish)
  {
    this. sections_publish = pages_publish;
  }
  
  
  @Override
  public String toString()
  {
    return this.getLoginName();
  }

  /** Users are compared by their login name */
  public int compareTo(RegisteredUser o)
  {
    if(o == null)
      return -1;
    
    return this.toString().compareTo(o.toString());
  }

  @Override
  public boolean equals(Object obj)
  {
    if(obj != null && obj instanceof RegisteredUser)
    {
      return ((RegisteredUser) obj).getId() == getId();
    }
    return false;
  }

  @Override
  public int hashCode()
  {
    int hash = 7;
    hash = 23 * hash + (int) (this.id ^ (this.id >>> 32));
    return hash;
  }
  
}
